home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / os2 / mpegenc / src / pbmplus / pbm / libpbm1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-01  |  13.1 KB  |  688 lines

  1. /* libpbm1.c - pbm utility library part 1
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pbm.h"
  14. #include "version.h"
  15. #include "libpbm.h"
  16. #if __STDC__
  17. #include <stdarg.h>
  18. #else /*__STDC__*/
  19. #include <varargs.h>
  20. #endif /*__STDC__*/
  21.  
  22. /* @@@ Ensure errno gets defined, Andy Key */
  23. #ifdef OS2
  24. #include <errno.h>
  25. #endif
  26.  
  27. /* Forward routines. */
  28.  
  29. #if defined(NEED_VFPRINTF1) || defined(NEED_VFPRINTF2)
  30. int vfprintf ARGS(( FILE* stream, char* format, va_list args ));
  31. #endif /*NEED_VFPRINTF*/
  32.  
  33.  
  34. /* Variable-sized arrays. */
  35.  
  36. char*
  37. pm_allocrow( cols, size )
  38.     int cols;
  39.     int size;
  40.     {
  41.     register char* itrow;
  42.  
  43.     itrow = (char*) malloc( cols * size );
  44.     if ( itrow == (char*) 0 )
  45.     pm_error( "out of memory allocating a row" );
  46.     return itrow;
  47.     }
  48.  
  49. void
  50. pm_freerow( itrow )
  51.     char* itrow;
  52.     {
  53.     free( itrow );
  54.     }
  55.  
  56.  
  57. char**
  58. pm_allocarray( cols, rows, size )
  59.     int cols, rows;
  60.     int size;
  61.     {
  62.     char** its;
  63.     int i;
  64.  
  65.     its = (char**) malloc( rows * sizeof(char*) );
  66.     if ( its == (char**) 0 )
  67.     pm_error( "out of memory allocating an array" );
  68.     its[0] = (char*) malloc( rows * cols * size );
  69.     if ( its[0] == (char*) 0 )
  70.     pm_error( "out of memory allocating an array" );
  71.     for ( i = 1; i < rows; ++i )
  72.     its[i] = &(its[0][i * cols * size]);
  73.     return its;
  74.     }
  75.  
  76. void
  77. pm_freearray( its, rows )
  78.     char** its;
  79.     int rows;
  80.     {
  81.     free( its[0] );
  82.     free( its );
  83.     }
  84.  
  85.  
  86. /* Case-insensitive keyword matcher. */
  87.  
  88. int
  89. pm_keymatch( str, keyword, minchars )
  90.     char* str;
  91.     char* keyword;
  92.     int minchars;
  93.     {
  94.     register int len;
  95.  
  96.     len = strlen( str );
  97.     if ( len < minchars )
  98.     return 0;
  99.     while ( --len >= 0 )
  100.     {
  101.     register char c1, c2;
  102.  
  103.     c1 = *str++;
  104.     c2 = *keyword++;
  105.     if ( c2 == '\0' )
  106.         return 0;
  107.     if ( isupper( c1 ) )
  108.         c1 = tolower( c1 );
  109.     if ( isupper( c2 ) )
  110.         c1 = tolower( c2 );
  111.     if ( c1 != c2 )
  112.         return 0;
  113.     }
  114.     return 1;
  115.     }
  116.  
  117.  
  118. /* Log base two hacks. */
  119.  
  120. int
  121. pm_maxvaltobits( maxval )
  122.     int maxval;
  123.     {
  124.     if ( maxval <= 1 )
  125.     return 1;
  126.     else if ( maxval <= 3 )
  127.     return 2;
  128.     else if ( maxval <= 7 )
  129.     return 3;
  130.     else if ( maxval <= 15 )
  131.     return 4;
  132.     else if ( maxval <= 31 )
  133.     return 5;
  134.     else if ( maxval <= 63 )
  135.     return 6;
  136.     else if ( maxval <= 127 )
  137.     return 7;
  138.     else if ( maxval <= 255 )
  139.     return 8;
  140.     else if ( maxval <= 511 )
  141.     return 9;
  142.     else if ( maxval <= 1023 )
  143.     return 10;
  144.     else if ( maxval <= 2047 )
  145.     return 11;
  146.     else if ( maxval <= 4095 )
  147.     return 12;
  148.     else if ( maxval <= 8191 )
  149.     return 13;
  150.     else if ( maxval <= 16383 )
  151.     return 14;
  152.     else if ( maxval <= 32767 )
  153.     return 15;
  154.     else if ( (long) maxval <= 65535L )
  155.     return 16;
  156.     else
  157.     pm_error( "maxval of %d is too large!", maxval );
  158.     }
  159.  
  160. int
  161. pm_bitstomaxval( bits )
  162.     int bits;
  163.     {
  164.     return ( 1 << bits ) - 1;
  165.     }
  166.  
  167.  
  168. /* Initialization. */
  169.  
  170. static char* progname;
  171. static int showmessages;
  172.  
  173. void
  174. pm_init( argcP, argv )
  175.     int* argcP;
  176.     char* argv[];
  177.     {
  178.     int argn, i;
  179.  
  180.     /* Extract program name. */
  181.     progname = rindex( argv[0], '/');
  182.     if ( progname == NULL )
  183.     progname = argv[0];
  184.     else
  185.     ++progname;
  186.  
  187.     /* Check for any global args. */
  188.     showmessages = 1;
  189.     for ( argn = 1; argn < *argcP; ++argn )
  190.     {
  191.     if ( pm_keymatch( argv[argn], "-quiet", 6 ) )
  192.         {
  193.         showmessages = 0;
  194.         }
  195.     else if ( pm_keymatch( argv[argn], "-version", 7 ) )
  196.         {
  197.         pm_message( "Version of %s", PBMPLUS_VERSION );
  198. #ifdef BSD
  199.         pm_message( "BSD defined" );
  200. #endif /*BSD*/
  201. #ifdef SYSV
  202.         pm_message( "SYSV defined" );
  203. #endif /*SYSV*/
  204. #ifdef MSDOS
  205.         pm_message( "MSDOS defined" );
  206. #endif /*MSDOS*/
  207. #ifdef PBMPLUS_RAWBITS
  208.         pm_message( "PBMPLUS_RAWBITS defined" );
  209. #endif /*PBMPLUS_RAWBITS*/
  210. #ifdef PBMPLUS_BROKENPUTC1
  211.         pm_message( "PBMPLUS_BROKENPUTC1 defined" );
  212. #endif /*PBMPLUS_BROKENPUTC1*/
  213. #ifdef PBMPLUS_BROKENPUTC2
  214.         pm_message( "PBMPLUS_BROKENPUTC2 defined" );
  215. #endif /*PBMPLUS_BROKENPUTC2*/
  216. #ifdef PGM_BIGGRAYS
  217.         pm_message( "PGM_BIGGRAYS defined" );
  218. #endif /*PGM_BIGGRAYS*/
  219. #ifdef PPM_PACKCOLORS
  220.         pm_message( "PPM_PACKCOLORS defined" );
  221. #endif /*PPM_PACKCOLORS*/
  222. #ifdef DEBUG
  223.         pm_message( "DEBUG defined" );
  224. #endif /*DEBUG*/
  225. #ifdef NEED_VFPRINTF1
  226.         pm_message( "NEED_VFPRINTF1 defined" );
  227. #endif /*NEED_VFPRINTF1*/
  228. #ifdef NEED_VFPRINTF2
  229.         pm_message( "NEED_VFPRINTF2 defined" );
  230. #endif /*NEED_VFPRINTF2*/
  231. #ifdef RGB_DB
  232.         pm_message( "RGB_DB=\"%s\"", RGB_DB );
  233. #endif /*RGB_DB*/
  234. #ifdef LIBTIFF
  235.         pm_message( "LIBTIFF defined" );
  236. #endif /*LIBTIFF*/
  237.         exit( 0 );
  238.         }
  239.     else
  240.         continue;
  241.     for ( i = argn + 1; i <= *argcP; ++i )
  242.         argv[i - 1] = argv[i];
  243.     --(*argcP);
  244.     }
  245.     }
  246.  
  247. void
  248. pbm_init( argcP, argv )
  249.     int* argcP;
  250.     char* argv[];
  251.     {
  252.     pm_init( argcP, argv );
  253.     }
  254.  
  255.  
  256. /* Error handling. */
  257.  
  258. void
  259. pm_usage( usage )
  260.     char* usage;
  261.     {
  262.     fprintf( stderr, "usage:  %s %s\n", progname, usage );
  263.     exit( 1 );
  264.     }
  265.  
  266. void
  267. pm_perror( reason )
  268.     char* reason;
  269.     {
  270. #ifdef OS2
  271.     char* e = strerror(errno);
  272. #else
  273.     extern char* sys_errlist[];
  274.     extern int errno;
  275.     char* e;
  276.  
  277.     e = sys_errlist[errno];
  278. #endif
  279.  
  280.     if ( reason != 0 && reason[0] != '\0' )
  281.     pm_error( "%s - %s", reason, e );
  282.     else
  283.     pm_error( "%s", e );
  284.     }
  285.  
  286. #if __STDC__
  287. void
  288. pm_message( char* format, ... )
  289.     {
  290.     va_list args;
  291.  
  292.     va_start( args, format );
  293. #else /*__STDC__*/
  294. /*VARARGS1*/
  295. void
  296. pm_message( va_alist )
  297.     va_dcl
  298.     { /*}*/
  299.     va_list args;
  300.     char* format;
  301.  
  302.     va_start( args );
  303.     format = va_arg( args, char* );
  304. #endif /*__STDC__*/
  305.  
  306.     if ( showmessages )
  307.     {
  308.     fprintf( stderr, "%s: ", progname );
  309.     (void) vfprintf( stderr, format, args );
  310.     fputc( '\n', stderr );
  311.     }
  312.     va_end( args );
  313.     }
  314.  
  315. #if __STDC__
  316. void
  317. pm_error( char* format, ... )
  318.     {
  319.     va_list args;
  320.  
  321.     va_start( args, format );
  322. #else /*__STDC__*/
  323. /*VARARGS1*/
  324. void
  325. pm_error( va_alist )
  326.     va_dcl
  327.     { /*}*/
  328.     va_list args;
  329.     char* format;
  330.  
  331.     va_start( args );
  332.     format = va_arg( args, char* );
  333. #endif /*__STDC__*/
  334.  
  335.     fprintf( stderr, "%s: ", progname );
  336.     (void) vfprintf( stderr, format, args );
  337.     fputc( '\n', stderr );
  338.     va_end( args );
  339.     exit( 1 );
  340.     }
  341.  
  342. #ifdef NEED_VFPRINTF1
  343.  
  344. /* Micro-vfprintf, for systems that don't have vfprintf but do have _doprnt.
  345. */
  346.  
  347. int
  348. vfprintf( stream, format, args )
  349.     FILE* stream;
  350.     char* format;
  351.     va_list args;
  352.     {
  353.     return _doprnt( format, args, stream );
  354.     }
  355. #endif /*NEED_VFPRINTF1*/
  356.  
  357. #ifdef NEED_VFPRINTF2
  358.  
  359. /* Portable mini-vfprintf, for systems that don't have either vfprintf or
  360. ** _doprnt.  This depends only on fprintf.  If you don't have fprintf,
  361. ** you might consider getting a new stdio library.
  362. */
  363.  
  364. int
  365. vfprintf( stream, format, args )
  366.     FILE* stream;
  367.     char* format;
  368.     va_list args;
  369.     {
  370.     int n;
  371.     char* ep;
  372.     char fchar;
  373.     char tformat[512];
  374.     int do_long;
  375.     int i;
  376.     long l;
  377.     unsigned u;
  378.     unsigned long ul;
  379.     char* s;
  380.     double d;
  381.  
  382.     n = 0;
  383.     while ( *format != '\0' )
  384.     {
  385.     if ( *format != '%' )
  386.         { /* Not special, just write out the char. */
  387.         (void) putc( *format, stream );
  388.         ++n;
  389.         ++format;
  390.         }
  391.     else
  392.         {
  393.         do_long = 0;
  394.         ep = format + 1;
  395.  
  396.         /* Skip over all the field width and precision junk. */
  397.         if ( *ep == '-' )
  398.         ++ep;
  399.         if ( *ep == '0' )
  400.         ++ep;
  401.         while ( isdigit( *ep ) )
  402.         ++ep;
  403.         if ( *ep == '.' )
  404.         {
  405.         ++ep;
  406.         while ( isdigit( *ep ) )
  407.             ++ep;
  408.         }
  409.         if ( *ep == '#' )
  410.         ++ep;
  411.         if ( *ep == 'l' )
  412.         {
  413.         do_long = 1;
  414.         ++ep;
  415.         }
  416.  
  417.         /* Here's the field type.  Extract it, and copy this format
  418.         ** specifier to a temp string so we can add an end-of-string.
  419.         */
  420.         fchar = *ep;
  421.         (void) strncpy( tformat, format, ep - format + 1 );
  422.         tformat[ep - format + 1] = '\0';
  423.  
  424.         /* Now do a one-argument fprintf with the format string we have
  425.         ** isolated.
  426.         */
  427.         switch ( fchar )
  428.         {
  429.         case 'd':
  430.         if ( do_long )
  431.             {
  432.             l = va_arg( args, long );
  433.             n += fprintf( stream, tformat, l );
  434.             }
  435.         else
  436.             {
  437.             i = va_arg( args, int );
  438.             n += fprintf( stream, tformat, i );
  439.             }
  440.         break;
  441.  
  442.             case 'o':
  443.             case 'x':
  444.             case 'X':
  445.             case 'u':
  446.         if ( do_long )
  447.             {
  448.             ul = va_arg( args, unsigned long );
  449.             n += fprintf( stream, tformat, ul );
  450.             }
  451.         else
  452.             {
  453.             u = va_arg( args, unsigned );
  454.             n += fprintf( stream, tformat, u );
  455.             }
  456.         break;
  457.  
  458.             case 'c':
  459.         i = (char) va_arg( args, int );
  460.         n += fprintf( stream, tformat, i );
  461.         break;
  462.  
  463.             case 's':
  464.         s = va_arg( args, char* );
  465.         n += fprintf( stream, tformat, s );
  466.         break;
  467.  
  468.             case 'e':
  469.             case 'E':
  470.             case 'f':
  471.             case 'g':
  472.             case 'G':
  473.         d = va_arg( args, double );
  474.         n += fprintf( stream, tformat, d );
  475.         break;
  476.  
  477.             case '%':
  478.         (void) putc( '%', stream );
  479.         ++n;
  480.         break;
  481.  
  482.         default:
  483.         return -1;
  484.         }
  485.  
  486.         /* Resume formatting on the next character. */
  487.         format = ep + 1;
  488.         }
  489.     }
  490.     return nc;
  491.     }
  492. #endif /*NEED_VFPRINTF2*/
  493.  
  494.  
  495. /* File open/close that handles "-" as stdin and checks errors. */
  496.  
  497. FILE*
  498. pm_openr( name )
  499.     char* name;
  500.     {
  501.     FILE* f;
  502.  
  503.     if ( strcmp( name, "-" ) == 0 )
  504.     f = stdin;
  505.     else
  506.     {
  507. /* @@@ Changed so that OS2 has binary too */
  508. #if defined(MSDOS) || defined(OS2)
  509.     f = fopen( name, "rb" );
  510. #else /*MSDOS*/
  511.     f = fopen( name, "r" );
  512. #endif /*MSDOS*/
  513.     if ( f == NULL )
  514.         {
  515.         pm_perror( name );
  516.         exit( 1 );
  517.         }
  518.     }
  519.     return f;
  520.     }
  521.  
  522. FILE*
  523. pm_openw( name )
  524.     char* name;
  525.     {
  526.     FILE* f;
  527.  
  528. /* @@@ Changed so that OS2 has binary too */
  529. #if defined(MSDOS) || defined(OS2)
  530.     f = fopen( name, "wb" );
  531. #else /*MSDOS*/
  532.     f = fopen( name, "w" );
  533. #endif /*MSDOS*/
  534.     if ( f == NULL )
  535.     {
  536.     pm_perror( name );
  537.     exit( 1 );
  538.     }
  539.     return f;
  540.     }
  541.  
  542. void
  543. pm_close( f )
  544.     FILE* f;
  545.     {
  546. #ifdef POSIX
  547.     fflush( f );
  548. #endif
  549.     if ( ferror( f ) )
  550.     pm_message( "a file read or write error occurred at some point" );
  551.     if ( f != stdin )
  552.     if ( fclose( f ) != 0 )
  553.         pm_perror( "fclose" );
  554.     }
  555.  
  556. /* Endian I/O.
  557. */
  558.  
  559. int
  560. pm_readbigshort( in, sP )
  561.     FILE* in;
  562.     short* sP;
  563.     {
  564.     int c;
  565.  
  566.     if ( (c = getc( in )) == EOF )
  567.     return -1;
  568.     *sP = ( c & 0xff ) << 8;
  569.     if ( (c = getc( in )) == EOF )
  570.     return -1;
  571.     *sP |= c & 0xff;
  572.     return 0;
  573.     }
  574.  
  575. #if __STDC__
  576. int
  577. pm_writebigshort( FILE* out, short s )
  578. #else /*__STDC__*/
  579. int
  580. pm_writebigshort( out, s )
  581.     FILE* out;
  582.     short s;
  583. #endif /*__STDC__*/
  584.     {
  585.     (void) putc( ( s >> 8 ) & 0xff, out );
  586.     (void) putc( s & 0xff, out );
  587.     return 0;
  588.     }
  589.  
  590. int
  591. pm_readbiglong( in, lP )
  592.     FILE* in;
  593.     long* lP;
  594.     {
  595.     int c;
  596.  
  597.     if ( (c = getc( in )) == EOF )
  598.     return -1;
  599.     *lP = ( c & 0xff ) << 24;
  600.     if ( (c = getc( in )) == EOF )
  601.     return -1;
  602.     *lP |= ( c & 0xff ) << 16;
  603.     if ( (c = getc( in )) == EOF )
  604.     return -1;
  605.     *lP |= ( c & 0xff ) << 8;
  606.     if ( (c = getc( in )) == EOF )
  607.     return -1;
  608.     *lP |= c & 0xff;
  609.     return 0;
  610.     }
  611.  
  612. int
  613. pm_writebiglong( out, l )
  614.     FILE* out;
  615.     long l;
  616.     {
  617.     (void) putc( ( l >> 24 ) & 0xff, out );
  618.     (void) putc( ( l >> 16 ) & 0xff, out );
  619.     (void) putc( ( l >> 8 ) & 0xff, out );
  620.     (void) putc( l & 0xff, out );
  621.     return 0;
  622.     }
  623.  
  624. int
  625. pm_readlittleshort( in, sP )
  626.     FILE* in;
  627.     short* sP;
  628.     {
  629.     int c;
  630.  
  631.     if ( (c = getc( in )) == EOF )
  632.     return -1;
  633.     *sP = c & 0xff;
  634.     if ( (c = getc( in )) == EOF )
  635.     return -1;
  636.     *sP |= ( c & 0xff ) << 8;
  637.     return 0;
  638.     }
  639.  
  640. #if __STDC__
  641. int
  642. pm_writelittleshort( FILE* out, short s )
  643. #else /*__STDC__*/
  644. int
  645. pm_writelittleshort( out, s )
  646.     FILE* out;
  647.     short s;
  648. #endif /*__STDC__*/
  649.     {
  650.     (void) putc( s & 0xff, out );
  651.     (void) putc( ( s >> 8 ) & 0xff, out );
  652.     return 0;
  653.     }
  654.  
  655. int
  656. pm_readlittlelong( in, lP )
  657.     FILE* in;
  658.     long* lP;
  659.     {
  660.     int c;
  661.  
  662.     if ( (c = getc( in )) == EOF )
  663.     return -1;
  664.     *lP = c & 0xff;
  665.     if ( (c = getc( in )) == EOF )
  666.     return -1;
  667.     *lP |= ( c & 0xff ) << 8;
  668.     if ( (c = getc( in )) == EOF )
  669.     return -1;
  670.     *lP |= ( c & 0xff ) << 16;
  671.     if ( (c = getc( in )) == EOF )
  672.     return -1;
  673.     *lP |= ( c & 0xff ) << 24;
  674.     return 0;
  675.     }
  676.  
  677. int
  678. pm_writelittlelong( out, l )
  679.     FILE* out;
  680.     long l;
  681.     {
  682.     (void) putc( l & 0xff, out );
  683.     (void) putc( ( l >> 8 ) & 0xff, out );
  684.     (void) putc( ( l >> 16 ) & 0xff, out );
  685.     (void) putc( ( l >> 24 ) & 0xff, out );
  686.     return 0;
  687.     }
  688.